<?php

// @formatter:off
/**
 * @file WCGroupsHolder.php
 * @author Alejandro Dario Simi
 * @date $Date: 2014-05-04 01:33:52 +0000 (Sun, 04 May 2014) $
 *
 * $Id: WCGroupsHolder.php 111 2014-05-04 01:33:52Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/trunk/includes/holders/WCGroupsHolder.php $
 */
// @formatter:on

/**
 * @class WCGroupsHolder This class is a holder for representations of table
 * '%groups', in other words, a holder for WCGroup objects.
 */
class WCGroupsHolder extends WCHolder {
	/**
	 * @var string Class name of the objects to be held.
	 */
	protected $_PropertiesItemClass = "WCGroup";
	/**
	 * @var string This is the prefix of every column on the table
	 * '%groups'.
	 */
	protected $_PropertiesPrefix = "grp_";
	/**
	 * @var string This is the name of the table represented by WCComic
	 * objects. In this case, '%groups'.
	 */
	protected $_PropertiesTable = "groups";
	/**
	 * @var WCConnection Database pointer shortcut.
	 */
	protected $_db = false;
	/**
	 * @var string Database tables' prefix shortcut.
	 */
	protected $_dbprefix = "";
	/**
	 * @var WCContainer List of public groups.
	 */
	protected $_public = false;
	/**
	 * Class constructor.
	 */
	protected function __construct() {
		//
		// Loading global pointers.
		global $wcDatabaseAccess;
		//
		// Loading shortcuts.
		// @{
		$this->_db = WCConnection::Instance();
		$this->_dbprefix = $wcDatabaseAccess["prefix"];
		// @}

		$this->createContainers();
	}
	//
	// Public methods.
	/**
	 * Creates a new group with default configurations
	 *
	 * @param string $name Name for the group.
	 * @param string $directory Root directory.
	 * @param string $trash Sub-directory where garbage has to be dropped.
	 * @return int Returns the id for the new group. On failure, returns false.
	 */
	public function add($name, $directory, $trash) {
		//
		// Loading global pointers.
		global $wcDefaults;
		//
		// Setting default value to be returned.
		$id = false;
		//
		// Checking that Read Only Mode is not activated.
		if(!$wcDefaults["read-only"]) {
			//
			// Building group's root directory full path.
			$directory = WCSanitizer::SystemPath($directory);
			//
			// Building group's trash directory full path.
			$trashPath = WCSanitizer::SystemPath("{$directory}{$trash}");
			//
			// Checking that:
			//	- The root directory is a valid directory.
			//	- If there's a trash directory specified, it is a
			//	  valid directory.
			if(is_dir($directory) && (!$trash || is_dir($trashPath))) {
				//
				// Creating a query to insert a new item.
				// @{
				$stmt = false;
				$stmtID = __CLASS__."::".__FUNCTION__;
				if($this->_db->has($stmtID)) {
					$stmt = $this->_db->get($stmtID);
				} else {
					$query = "insert\n";
					$query .= "        into {$this->_dbprefix}groups (\n";
					$query .= "                grp_name, grp_root, grp_trash)\n";
					$query .= "        values (:name, :directory, :trash)\n";
					$stmt = $this->_db->prepare($stmtID, $query);
				}
				// @}
				//
				// Building database parameters.
				$params = array(
					":name" => $name,
					":directory" => $directory,
					":trash" => $trash
				);
				//
				// Attempting to create the new group.
				if($stmt->execute($params)) {
					//
					// At this point, group was created.
					$id = $this->_db->lastInsertId();
				}
			}
			//
			// Reloading all groups.
			// @{
			$this->_fullLoaded = false;
			$this->items();
			// @}
			//
			// When a new group is created it has no directories,
			// therefore, it is force to have it's first one.
			if($id) {
				//
				// Always, first directory is slash... no, not the
				// guitarist.
				$dirname = "/";
				//
				// Getting the new group.
				$group = $this->item($id);
				//
				// Adding the first directory.
				$auxDir = WCDirectoriesHolder::I()->createInGroup($dirname, $group);
				WCDirectoriesHolder::I()->resetCache();
			}
			//
			// Adding trash directory.
			if($id && $trash) {
				//
				// Getting the new group.
				$group = $this->item($id);
				//
				// Adding trash directory.
				$auxDir = WCDirectoriesHolder::I()->createInGroup($trash, $group);
				WCDirectoriesHolder::I()->resetCache();
			}
		}
		//
		// Returning newly created object.
		return $id;
	}
	public function create($name) {
		trigger_error(__CLASS__."::".__FUNCTION__."(): This method is not supported. Use '".__CLASS__."::"."add()'.", E_USER_ERROR);
	}
	/**
	 * This method allows to get a list of public groups..
	 *
	 * @return WCGroup[] Returns a list of public groups.
	 */
	public function publicGroups() {
		return $this->_public->items();
	}
	/**
	 * This method allows to load all internal lists.
	 *
	 * @return boolean Returns true when it successfully loads.
	 */
	public function reload() {
		//
		// Restarting internal lists.
		// @{
		$this->_public = false;
		// @}
		//
		// Calling main loader and returning its result.
		$this->createContainers();
	}
	//
	// Protected methods.
	protected function addToCache(&$item) {
		$out = false;

		if(parent::addToCache($item)) {
			if($item->isPublic()) {
				$this->_public->addItem($item->id, $item);
			}

			$out = true;
		}

		return $out;
	}
	/**
	 * The method creates all required containers.
	 */
	protected function createContainers() {
		//
		// Public group container.
		if($this->_public == false) {
			//
			// Creating a list for public groups.
			$this->_public = new WCContainer($this);
		}
	}
}
